﻿import { GlobalData } from "../Config/GlobalData";
import FightModuleS from "./FightModuleS";
import FightTimeUI from "./FightTimeUI";


class PropInfo_C {
    /**道具唯一id */
    public key: number;
    /**道具表id */
    public id: number;
    /**道具Tag */
    public tag: number;
    /**道具对象 */
    public obj: GameObject;

}



export default class FightModuleC extends ModuleC<FightModuleS, null> {


    private timer: number; // 定时器ID

    /**道具数组 */
    private propList: PropInfo_C[] = [];

    /**当前选中道具 */
    private curSelectKey: number = null;

    // 必须先获取到此UI的实例才能对其内部控件进行操作（大概）
    private fightTimeUI: FightTimeUI = UIService.show(FightTimeUI)
    // 定义记录选中道具信息的变量
    private selectedProp: GameObject | null = null; // 选中的道具实体对象
    private originalPosition: Vector | null = null; // 选中道具的原始位置

    private triggeredExtraTime: Boolean = false;//是否触发过额外时间


    /** 当脚本被实例后，会在第一帧更新前调用此函数 */
    protected onStart(): void {

        // 在开始时启动定时器，每秒执行一次 handlePlayerTurnTime 方法
        this.timer = setInterval(() => {
            this.handlePlayerTurnTime();
        }, 1000); // 每秒执行一次

        let camera = Camera.currentCamera;
        // 点击选中桌上的道具
        InputUtil.onTouchEnd((index: number, location: Vector2) => {
            let res = InputUtil.convertScreenLocationToWorldSpace(location.x, location.y);
            let dir = res.worldDirection;
            let startPos = camera.worldTransform.position;
            let endPos = Vector.add(startPos, Vector.multiply(dir, GlobalData.Prop.lineTraceLength));
            console.log(`start: ${startPos}, end: ${endPos}`)

            // 第四个参数是可视化绘制，为了更好地观测动画效果暂时关闭
            let lineRes = QueryUtil.lineTrace(startPos, endPos, true, false);

            console.log("目标数量" + lineRes.length);

            // 标记是否选中了道具
            let foundProp = false;
            // 筛选出符合条件的第一个物体并执行操作
            for (let res of lineRes) {
                if (res.gameObject.tag === "prop") {
                    // 执行选中道具动画
                    this.selectProp(res.gameObject);
                    foundProp = true;
                    break; // 找到符合条件的第一个物体后，跳出循环
                }
            }
            // 如果没有找到符合条件的道具，则取消选中的道具
            if (!foundProp) {
                this.deselectProp();
            }
        })
    }

    // 在脚本销毁时清除定时器，防止内存泄漏
    protected onDestroy(): void {
        clearInterval(this.timer); // 清除定时器
    }

    /** 选中道具动画 */
    private async selectProp(obj: GameObject) {
        // 检查是否与之前选中的物体相同
        if (this.selectedProp === obj) {
            // 如果相同，执行使用道具逻辑
            console.log("使用道具")
            // 增加思考时间
            this.increaseThinkTime()
            // 然后将物体回到原始位置
            this.restorePropToDefault();
            return; // 退出函数，不执行下面的动画逻辑
        }

        // 检查记录的选中道具实体对象和原始位置是否存在数据
        if (this.selectedProp && this.originalPosition) {
            // 存在数据，恢复上一个选中的道具到默认位置
            this.restorePropToDefault();
        }
        // 记录当前选中的道具实体对象和原始位置
        this.selectedProp = obj;
        this.originalPosition = obj.worldTransform.position.clone();

        // 设置目标位置，沿着z轴向上移动一定距离
        let targetZ = this.originalPosition.z + 10; // 向上移动10个单位

        // 创建动画效果，将物体移动到目标位置
        let targetPosition = new Vector(obj.worldTransform.position.x, obj.worldTransform.position.y, targetZ);
        let tween = new Tween(obj.worldTransform.position).to(targetPosition, 300).onUpdate((position) => {
            // 每一次更新，改变物体位置
            obj.worldTransform.position = position;
        });
        tween.start();

    }
    // 恢复选中道具到默认位置的函数
    private restorePropToDefault() {
        if (this.selectedProp && this.originalPosition) {
            /* 这里需要设置一个temp来临时存储上次选中的道具对象，因为在动画执行过程中
            上次存储的对象会被重置为null，导致动画无法执行*/
            let temp = this.selectedProp;
            // 创建动画，将选中道具移动到原始位置
            let tween = new Tween(temp.worldTransform.position)
                .to(this.originalPosition, 150)
                .onUpdate((position) => {
                    // 每一次更新，改变道具位置
                    temp.worldTransform.position = position;
                });
            tween.start();

            // 重置记录的选中道具信息为 null
            this.selectedProp = null;
            this.originalPosition = null;
        }
    }
    // 取消选中道具，恢复默认位置
    private deselectProp() {
        // 检查记录的选中道具信息是否存在数据
        if (this.selectedProp && this.originalPosition) {
            // 存在数据，恢复选中道具到默认位置
            this.restorePropToDefault();
        }
    }

    public handlePlayerTurnTime(): void {
        // 每秒执行一次此方法，进行玩家回合时间的处理
        // 减少思考时间
        GlobalData.Time.thinkTime--;

        // 检查思考时间是否为0
        if (GlobalData.Time.thinkTime === 0) {
            if (!this.triggeredExtraTime && GlobalData.Time.reserveTime > 0) {
                // 触发额外时间
                this.triggerExtraTime();
            } else {
                // 结束玩家此次回合
                this.endPlayerTurn();
            }
        }
    }
    // 玩家进行操作时增加思考时间
    public increaseThinkTime(): void {
        // 检查是否超过最大时间
        if (GlobalData.Time.thinkTime < GlobalData.Time.maxTime) {
            GlobalData.Time.thinkTime += 2;
            // 确保不超过最大时间
            if (GlobalData.Time.thinkTime > GlobalData.Time.maxTime) {
                GlobalData.Time.thinkTime = GlobalData.Time.maxTime;
            }
        }
        // 更新UI显示
        this.fightTimeUI.increaseThinkTimeAndUI(2); // 传入增加的时间
    }

    // 玩家回合结束时重置时间
    public resetTime(): void {
        // 重置思考时间为默认值
        GlobalData.Time.thinkTime = 15;
        // 重置是否触发过额外时间为否
        this.triggeredExtraTime = false;
    }

    // 触发额外时间
    private triggerExtraTime(): void {
        GlobalData.Time.reserveTime -= GlobalData.Time.extraTime;
        GlobalData.Time.thinkTime += GlobalData.Time.extraTime;
        // 设置触发额外时间为true
        this.triggeredExtraTime = true;
        this.fightTimeUI.increaseThinkTimeAndUI(5); // 传入增加的时间
        this.fightTimeUI.decreaseReserveTimeAndUI(5); // 传入减少的时间


    }

    // 结束玩家此次回合
    private endPlayerTurn(): void {
        // 清除选中的道具
        this.selectedProp = null;
        this.originalPosition = null;
        // 重置时间
        this.resetTime();

        // 此处应该添加轮到对方回合和自动攻击操作
    }
}